- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-19-2018 02:05 PM
I am using the slush bucket widget on a portal page so I can use a m2m table to link multiple songs to a gig. I have the songs in in the 'available' bucket and the widget works for me, but I am struggling to work out how to make the 'save' work like it would in the CMS through the edit option.
I am trying to decide if I should create a save button on the widget or if I should have the save button on the record form do the save once the songs are added to the gig.
If I do the slush widget (which I have been attempting to do now) I have attempted to take some of the code from the record widget save button but I am struggling with that. Which is what made me think about using that button to save the details in the slush widget.
Any suggestions on the best way to tackle this?
I looked at the list collector option as a variable on the form, but I couldn't work out how to make the songs save in the related list as I needed.
Below is the widget code I have so far
html
<div>
<h4>Select songs for this gig</h4>
<button type="button" class="btn btn-primary action-btn">Save songs</button>
<button ng-if="getPrimaryAction()" type="submit" ng-click="triggerUIAction(getPrimaryAction())" ng-disabled="submitting" class="btn btn-primary action-btn pull-right ng-scope" gsft_id="{{::action.sys_id}}">Save selections<!-- ngIf: saveButtonSuffix --><span ng-if="saveButtonSuffix" class="ng-binding ng-scope">(Ctrl + s)</span><!-- end ngIf: saveButtonSuffix --></button>
<div class="row">
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">${Select from below}</h4>
</div>
<div class="available list-group slush-scrollable"
as-sortable="c.availableAs"
ng-model="c.data.all">
<div ng-repeat="item in c.data.all | filter:c.search"
as-sortable-item
ng-dblclick="c.onDblClick(item)"
ng-class="{used: item.used}"
class="list-group-item">
<div as-sortable-item-handle>
<span>{{item.u_song_title.display_value}}</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">${In gig}</h4>
</div>
<div class="list-group slush-scrollable" as-sortable="c.selectedAs" ng-model="c.selected">
<div ng-repeat="item in c.selected"
as-sortable-item
ng-dblclick="c.onSelDblClick(item)"
class="list-group-item">
<div as-sortable-item-handle>
<span>{{item.u_song_title.display_value}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
</div>
</div>
CSS
.as-sortable-placeholder {
background-color: #eee;
}
.slush-scrollable {
height: 240px;
overflow-y: scroll;
overflow-x:hidden;
}
.panel > .list-group:last-child .list-group-item:last-child {
border-bottom-width: 1px;
border-bottom-style: solid;
border-radius: 0;
}
.used {
max-height: 0;
overflow: hidden;
padding: 0;
border: none;
}
.available > .list-group-item {
transition: all 1s;
}
.btn-form-menu {
vertical-align: inherit;
padding: inherit;
background: none;
}
Client
function($rootScope, $scope) {
var c = this;
c.selected = [];
// ng-sortable clone means cannot reorder
c.availableAs = {
itemMoved: function (event) {
event.source.itemScope.item.used = true;
},
clone: true // clone this side
}
c.selectedAs = {
itemMoved: function (event) {
// moved back to available
var item = event.source.itemScope.item;
moveToAvailable(item);
removeItem(c.data.all, item);
},
dragStart: function () {
c.availableAs.clone = false;
},
dragEnd: function () {
c.availableAs.clone = true;
}
}
// double moves from Available to Selected
c.onDblClick = function(item) {
var t = angular.copy(item);
item.used = true; // original is now used
c.selected.push(t);
}
// double on selected removes and unsets Available used
c.onSelDblClick = function(item) {
moveToAvailable(item);
removeItem(c.selected, item);
}
function removeItem(array, item) {
var n = array.indexOf(item);
if (n !== -1)
array.splice(n, 1);
}
function moveToAvailable(item) {
var t = item.sys_id.value;
angular.forEach(c.data.all, function(target) {
if (target.sys_id.value == t)
target.used = false;
})
}
function _save() {
var primaryAction = $scope.getPrimaryAction();
if (primaryAction)
$scope.triggerUIAction(primaryAction);
}
$scope.triggerUIAction = function(action) {
if ($scope.data.disableUIActions && !action.primary) {
return;
}
}
}
server
(function () {
// grab the filtered songs
data.all = [];
var filterQuery = "u_perform_statusIN1,2,3^u_song_status=2";
var gr = new GlideRecord('x_120100_band_songs');
gr.orderBy('u_song_title');
gr.addEncodedQuery(filterQuery);
gr.query();
while (gr.next()) {
var t = $sp.getRecordElements(gr, 'u_song_title,sys_id');
data.all.push(t);
}
})();
Solved! Go to Solution.
- Labels:
-
Service Portal Development
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-21-2018 05:31 AM
Hi Walshy,
In your server script for the input:
addSong.songs = input.songs[indx]
should be
addSong.songs = input.songs[indx].sys_id.value
according to your screenshot of the Object and if the "songs" field is a reference field on the m2m table.
Also as a side note to clear things up a little in your comments of your Client Script in the server.get() method. (Hopefully you don't mind)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-20-2018 06:10 PM
Hi Malgorzata,
I get what you have done here, but I think I have missed a step.
I went to the console as you suggested and I get an error based around the 'get' inside the c.saveMySongs, it is telling me the get is undefined for some reason, that doesn't make sense to me.
From the $scope console it looks like I am getting the gig sysID no worries, but the songs are not going into the c.selected array I am assuming this is because the 'get' is undefined from earlier in the client side code.
Im attempting to understand why the 'get' in the saveMySongs is being annoying.
Thanks
Cam.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-20-2018 06:19 PM
it should be c.server and you have
c.sever.get(
I missed "r" in my example
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-20-2018 10:21 PM
Yeah bad typo on my behalf, I should have read through a little closer.
That worked Malgorzata, I now just have to make sure the name of the song passes through to the m2m table.
The m2m table fills with the gig number, but the name of the song doesn't come through, ha! the sysID and the song titles come through in the array, but when you look at the m2m table, the songs field is empty. On the m2m table this is a reference field to the x_120100_band_songs table.
So when I look at related list table in the CMS I have no song name
But the gig and song are matching in the m2m table.
I have played around with a few different thoughts on the r.data.u_song_title in the client script thinking I needed to have the title point to the reference field somehow by doing r.data.songs.u_song_title but to no avail.
I understand the logic of the =input.songs[indx]; as it takes the 3 fields I have pushed back via r.data from the client script. But I cant work out how to make the name of the song show up in the m2m.
When I open the record in the m2m table it is a new blank record, so do I need to run a query on the x_120100_band_songs table to search for the song rather than add.Song.insert()?
client
c.saveMySongs = function(){
//pass the data to server in order to save
c.server.get(
{
action:'saveSongs',
songs: c.selected
}
)
.then(function(r){
//pass the required song data back to server
c.data.sys_id = r.data.sys_id;
c.data.number = r.data.number;
c.data.u_song_title = r.data.u_song_title;
});
}
Server
(function () {
// grab the filtered songs
data.all = [];
var filterQuery = "u_perform_statusIN1,2,3^u_song_status=2";
var gr = new GlideRecord('x_120100_band_songs');
gr.orderBy('u_song_title');
gr.addEncodedQuery(filterQuery);
gr.query();
while (gr.next()) {
var t = $sp.getRecordElements(gr, 'u_song_title,sys_id');
data.all.push(t);
}
// get the sys_id of the current gig from the URL
data.gigSysId = $sp.getParameter("sys_id");
console.log(input.gigSys_Id); // sys_is of your record
// save the song to the gig in the m2m table
if (input.action == 'saveSongs'){
for(var indx in input.songs){
var addSong = new GlideRecord('x_120100_band_m2m_set_list');
addSong.initialize();
addSong.gigs=data.gigSysId;
addSong.songs=input.songs[indx];
addSong.insert();
console.log(input.songs); // should be your list of sys_ids for the song
}
}
})();
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-21-2018 05:31 AM
Hi Walshy,
In your server script for the input:
addSong.songs = input.songs[indx]
should be
addSong.songs = input.songs[indx].sys_id.value
according to your screenshot of the Object and if the "songs" field is a reference field on the m2m table.
Also as a side note to clear things up a little in your comments of your Client Script in the server.get() method. (Hopefully you don't mind)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-21-2018 04:46 PM
Can I just say a massive thanks to everyone here.
I have it working now AND have the filters reading off the sys_ID from URL so the sets the songs go into for the gig work.
I love this place, everyone is so helpful.
Chris this is the second time you have come to my aid, so thank you very much!